﻿using System;
using System.Collections;
using Core.Scene;
using Utils;
using Utils.Coroutine;

namespace Core.Step
{
    /// <summary>
    /// 表示一个主要步骤，管理步骤名称、状态以及场景切换。
    /// </summary>
    public abstract class StepBase
    {
        public int StepNumber { get; } //步骤编号
        public int SubNumber { get; } //步骤子编号
        public string Name { get; } //步骤名称

        // 上一个步骤状态
        private StepStatus _lastStatus = StepStatus.NotCompleted;

        // 当前步骤状态
        private StepStatus _currentStatus = StepStatus.NotCompleted;

        // 步骤状态改变时的事件
        public event Action<StepStatus> OnStatusChanged;

        public event Action OnCompleted;

        // 动作队列，用于处理异步操作
        private ActionQueue _actionQueue;

        /// <summary>
        /// 构造函数，初始化步骤的名称。
        /// </summary>
        /// <param name="subNumber">步骤的子编号</param>
        /// <param name="name">步骤的名称</param>
        /// <param name="stepNumber">步骤的编号</param>
        protected StepBase(int stepNumber, int subNumber, string name)
        {
            StepNumber = stepNumber;
            SubNumber = subNumber;
            Name = name;
        }

        protected StepBase(string stepId, string name)
        {
            string[] split = stepId.Split('-');
            StepNumber = int.Parse(split[0]);
            SubNumber = int.Parse(split[1]);
            Name = name;
        }

        /// <summary>
        /// 当前步骤的状态，包含管理和触发状态改变的逻辑。
        /// </summary>
        public StepStatus CurrentStatus
        {
            private set
            {
                if (value == StepStatus.Completed)
                    _lastStatus = StepStatus.Completed; // 更新上一个状态
                _currentStatus = value; // 设置当前状态
                OnStatusChanged?.Invoke(value); // 触发状态改变事件
            }
            get => _currentStatus; // 获取当前状态
        }

        /// <summary>
        /// 当步骤进入时调用，记录为进行中状态并初始化动作队列。
        /// </summary>
        internal void Enter()
        {
            CurrentStatus = StepStatus.InProgress; // 设置为进行中状态
            _actionQueue = new ActionQueue();
            if (!SceneSystem.Singleton.IsSameScene(SceneInfo))
                _actionQueue.Append(SceneSystem.Singleton.LoadSceneCoroutine(SceneInfo)); //加载目标场景
            _actionQueue.Append(OnEnter())
                .Append(CompleteStep)
                .Append(OnCompleted)
                .Run();
        }

        /// <summary>
        /// 当步骤退出时调用，恢复上一个状态并停止动作队列。
        /// </summary>
        internal void Exit()
        {
            OnExit(); // 执行具体退出逻辑
            CurrentStatus = _lastStatus; // 恢复上一个状态
            // OnStatusChanged?.Invoke(CurrentStatus);
            // 停止未完成的动作队列
            _actionQueue?.Cancel();
        }

        /// <summary>
        /// 完成步骤的逻辑
        /// </summary>
        protected void CompleteStep()
        {
            _lastStatus = StepStatus.Completed; // 设置为已完成状态
        }

        /// <summary>
        /// 场景信息
        /// </summary>
        protected abstract SceneInfo SceneInfo { get; }


        /// <summary>
        /// 子类必须实现以定义进入步骤的具体逻辑。
        /// </summary>
        protected abstract IEnumerator OnEnter();

        /// <summary>
        /// 子类必须实现以定义退出步骤的具体逻辑。
        /// </summary>
        protected abstract void OnExit();
    }
}